function fromwhere = extcaller(varargin)
% extcaller  - from where was a call issued
%
% FORMAT:       callername = extcaller
%
% No input fields.
%
% Output fields:
%
%       callername  string identifying function name of calling function
%
% See also DBSTACK

% Version:  v0.7f
% Build:    8110521
% Date:     Nov-05 2008, 9:00 PM CET
% Author:   Jochen Weber, SCAN Unit, Columbia University, NYC, NY, USA
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% persistent versioning information
persistent ec_mlv;
if isempty(ec_mlv)
    ec_mlv = version;
    if ec_mlv(1) > '6'
        ec_mlv = 'file';
    else
        ec_mlv = 'name';
    end
end

% how to get stack info
switch (ec_mlv), case {'file'}
    pathstack = dbstack('-completenames');
case {'name'}
    pathstack = dbstack;
otherwise
    error( ...
        'BVQXtools:MemoryCorruption', ...
        'Interal variable glitch.' ...
    );
end

% set default caller name
fromwhere = 'CONSOLE_OR_GUI';
if numel(pathstack) < 3
    return;
end

% input argument handling
if nargin < 1
    func = lower(pathstack(2).(ec_mlv));

elseif ischar(varargin{1})
    func = lower(varargin{1});

elseif isnumeric(varargin{1}) && ...
   ~isempty(varargin{1}) && ...
   ~isnan(varargin{1}(1))
    func = lower(pathstack(2).(ec_mlv));
    if varargin{1}(1) == 1
        func = fileparts(func);
    end

else
    error( ...
        'BVQXtools:BadArgument', ...
        'Unsupported input argument.' ...
    );
end

% try to find matching caller
for dbsi = 3:numel(pathstack)
    if isempty(strfind(lower(pathstack(dbsi).(ec_mlv)), func))
        break;
    end
end
if dbsi < numel(pathstack) || ...
    isempty(strfind(lower(pathstack(dbsi).(ec_mlv)), func))
    fromwhere = pathstack(dbsi).(ec_mlv);
end
